#pragma once
//============================================================================
// Copyright (C) 2013 Brett R. Jones
//
// Issued to public domain 2013
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include "VxDefs.h"
#include "VxNetIdentBase.h"

// forward declare
class VxSktBase;

#define MAX_ONLINE_DESC_LEN		28	//maximum length of online description including 0 terminator

//! enumerated application State
enum EAppState
{
	eAppStateInvalid		= 0,	// unknown or disabled
	eAppStateStartup		= 1,	// app has started
	eAppStateShutdown		= 2,	// app shutdown
	eAppStateSleep			= 3,	// app sleep
	eAppStateWake			= 4,	// app wake
	eAppStatePause			= 5,	// pause app
	eAppStateResume			= 6,	// resume
	eAppStatePermissionErr	= 7,	// disabled by permission
	eAppStateInactive		= 8,	// inactive due to no files or error etc

	eMaxAppState // must be last.. maximum application states
};

#define USE_PLUGIN_WEB_SERVER		1
#define USE_PLUGIN_RELAY			1
#define USE_PLUGIN_CAM_SERVER		1
#define USE_PLUGIN_INST_MSG			1
#define USE_PLUGIN_VOICE_PHONE		1
#define USE_PLUGIN_VIDEO_PHONE		1
#define USE_PLUGIN_TRUTH_OR_DARE	1
#define USE_PLUGIN_FILE_OFFER		1
#define USE_PLUGIN_FILE_SERVER		1
//#define USE_PLUGIN_STORY_BOARD	1

//! enumerated plugin for rogue connections
enum EPluginType
{
	// don't handle packets for ePluginTypeInvalid or ePluginTypeWebServer
	ePluginTypeInvalid			= 0,	// unknown or disabled
#ifdef USE_PLUGIN_WEB_SERVER
	ePluginTypeWebServer		= 1,	// web server plugin ( for profile web page )
#endif
#ifdef USE_PLUGIN_RELAY
	ePluginTypeRelay			= 2,	// Relay plugin
#endif
#ifdef USE_PLUGIN_CAM_SERVER
	ePluginTypeCamServer		= 3,	// web cam broadcast plugin
#endif // USE_PLUGIN_CAM_SERVER
#ifdef USE_PLUGIN_INST_MSG
	ePluginTypeInstMsg			= 4,	// instant message p2p plugin
#endif // USE_PLUGIN_INST_MSG
#ifdef USE_PLUGIN_VOICE_PHONE
	ePluginTypeVoicePhone		= 5,	// VOIP p2p plugin
#endif // USE_PLUGIN_VOICE_PHONE
#ifdef USE_PLUGIN_VIDEO_PHONE
	ePluginTypeVideoPhone		= 6,	// Video phone p2p plugin
#endif // USE_PLUGIN_VIDEO_PHONE
#ifdef USE_PLUGIN_TRUTH_OR_DARE
	ePluginTypeTruthOrDare		= 7,	// Web Cam Truth Or Dare game p2p plugin
#endif // USE_PLUGIN_TRUTH_OR_DARE
#ifdef USE_PLUGIN_FILE_OFFER
	ePluginTypeFileOffer		= 8,	// offer to send a file plugin
#endif // USE_PLUGIN_FILE_OFFER
#ifdef USE_PLUGIN_FILE_SERVER
	ePluginTypeFileServer		= 9,	// file share plugin
#endif // USE_PLUGIN_FILE_SERVER
#ifdef USE_PLUGIN_STORY_BOARD
	ePluginTypeStoryBoard		= 10,	// story board plugin
#endif // USE_PLUGIN_STORY_BOARD

    eMaxPluginType				= 11,
    eStoryBoardWritePermission  = 15,	// only story board plugin read permission
	
	// fake plugin types without a actual plugin
    ePluginTypeSearch           = 17	// Web Cam Truth Or Dare game p2p plugin
};

//! describe plugin local name
const char * DescribePluginLclName( EPluginType ePluginType );
//! describe plugin remote name
const char * DescribePluginRmtName( EPluginType ePluginType );

enum EOfferResponse
{
	eOfferResponseNotSet		= 0,
	eOfferResponseAccept		= 1,
	eOfferResponseReject		= 2,
	eOfferResponseBusy			= 3,
	eOfferResponseCancelSession	= 4,
	eOfferResponseEndSession	= 5,
	eOfferResponseUserOffline	= 6
};

enum EFriendViewType
{
	eFriendViewEverybody		= 0,
	eFriendViewFriendsAndGuests = 1,
	eFriendViewAnonymous		= 2,
	eFriendViewIgnored			= 3,
	eFriendViewMyProxies		= 4,
	eFriendViewAllProxies		= 5,
	eFriendViewRefresh			= 6,

	eMaxFriendViewType // must be last
};

enum EPluginAccessState
{
    ePluginAccessOk				= 0,	// plugin access allowed
	ePluginAccessLocked			= 1,	// insufficient Friend permission level
	ePluginAccessDisabled		= 2,	// plugin disabled or no files shared or no web cam broadcast
	ePluginAccessIgnored		= 3,	// access denied because you are being ignored
	ePluginAccessInactive		= 4,	// enabled and have access but no shared files or web cam
	ePluginAccessBusy			= 5		// sufficient permission but cannot accept any more sessions
};

enum ERelayStatus
{
	eRelayStatusOk				= 0,	// proxy enabled and access accepted 
	eRelayStatusPermissionErr	= 1,	// insufficient permission
	eRelayStatusBusy			= 2		// proxy cannot accept any more session
};

// bits 0-3		WebServer
// bits 4-7		Relay
// bits 8-11	CamServer
// bits 12-15	InstMsg
// bits 16-29	VoicePhone
// bits 20-23	VideoPhone
// bits 24-27	TruthOrDare 
// bits 28-31	FileOffer
// bits 32-35   FileServer
// bits 36-63	reserved for future plugins
#define DEFAULT_PLUGIN_PERMISSIONS (0x1111111111111111ULL)
#pragma pack(push) 
#pragma pack(1)
//! 8 bytes in size
class PluginPermission
{
public:
	//=== vars ===//
	U64		m_u64Permissions;

	//=== constructor ===//
	PluginPermission();

	//=== methods ===//
	bool			isPluginEnabled( EPluginType ePlugin );
	//! get type of permission user has set for given plugin
	EFriendState	getPluginPermission( EPluginType ePluginType ); 
	//! set type of permission user has set for given plugin
	void			setPluginPermission( EPluginType ePluginType, EFriendState eFriendState ); 
	//! set all permissions
	void			setPluginPermissions( U64 u64Permissions );
};

#define APP_VERSION 0x0100

//! size 68 + 8 = 76 bytes derived from
//! 76 + 28 + 4 + 2 + 1 + 1 = 96 bytes + res 16 = 112 bytes
class VxNetIdent : public VxNetIdentBase, public PluginPermission
{
public:

	//=== vars ===//
	char		m_as8OnlineDesc[ MAX_ONLINE_DESC_LEN ]; // users online description 28 bytes
	U32			m_u32TimeTcpLastContact;				// last tcp contact ( used as part of rating )
	U32			m_u32TruthCnt;							// 
	U32			m_u32DareCnt;							// 
	U32			m_u32RejectedCnt;						// 
	U32			m_u32AvatarTimeLastChange;				// 
	U16			m_u16AvatarId;							// 
	U16			m_u16AppVersion;						// 
	U16			m_u16PingTimeMs;						// 
	U16			m_u16NetRes1;							// 
	U32			m_u32NetRes2;							// 
	U32			m_u32NetRes3;							// 
	U32			m_u32NetRes4;							// 

	//=== methods ===//
	//=== constructor ===//
	VxNetIdent();

	void	setTruthCount( U32 truthCnt );
	U32		getTruthCount();
	void	setDareCount( U32 dareCnt );
	U32		getDareCount();
	void	setRejectedCount( U32 truthCnt );
	U32		getRejectedCount();

	//! return users online description
	char *	getOnlineDescription( void );
	//! return users online description as string
	void	getOnlineDescription( std::string& strRetDesc );
	//! set users online description
	void 	setOnlineDescription( const char * pUserDesc );

	EPluginAccessState	getPluginAccessState( EPluginType ePluginType );

	EPluginAccessState	getPluginAccessState( EPluginType ePluginType, EFriendState eHisPermissionToMe );

	bool				isAccessAllowed( EPluginType ePluginType );

	//! copy operator
	VxNetIdent& operator =( const VxNetIdent &a );
	//! dump identity
	void debugDumpIdent( void );
};
#pragma pack(pop)

//! report a attempt to hack or add spyware etc
RCODE VxReportHack(	VxNetIdentBase *	poContactIdent,			// users identity info ( may be null if not known then use ipAddress )
					U32					u32HackLevel,			// 1=severe 2=medium 3=suspicious
					U32					u32IpAddr,				// ip address if identity not known
					const char *		pDescription, ... );	// description of hack attempt
